package com.cll.service.impl;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.cll.constant.MessageConstant;
import com.cll.constant.PasswordConstant;
import com.cll.constant.StatusConstant;
import com.cll.context.BaseContext;
import com.cll.dto.EmployeeDTO;
import com.cll.dto.EmployeeLoginDTO;
import com.cll.dto.EmployeePageQueryDTO;
import com.cll.entity.Employee;
import com.cll.exception.AccountLockedException;
import com.cll.exception.AccountNotFoundException;
import com.cll.exception.PasswordErrorException;
import com.cll.mapper.EmployeeMapper;
import com.cll.result.PageResult;
import com.cll.service.EmployeeService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.DigestUtils;

import java.time.LocalDateTime;

@Service
@Slf4j    //日志输出
//@Transactional   //事务
public class EmployeeServiceImpl implements EmployeeService {

    @Autowired
    private EmployeeMapper employeeMapper;

    /**
     * 员工登录
     *
     * @param employeeLoginDTO
     * @return
     */
    public Employee login(EmployeeLoginDTO employeeLoginDTO) {

        //测试Thread  后端tomcat服务器是不是都会去分配员工单独的线程来处理请求
        log.info("当前线程id:{}",Thread.currentThread().getId());

        String username = employeeLoginDTO.getUsername();
        String password = employeeLoginDTO.getPassword();

        //1、根据用户名查询数据库中的数据
        Employee employee = employeeMapper.getByUsername(username);

        //2、处理各种异常情况（用户名不存在、密码不对、账号被锁定）

        if (employee == null) {
            //账号不存在
            throw new AccountNotFoundException(MessageConstant.ACCOUNT_NOT_FOUND);
        }

        //密码比对
        // TODO 后期需要进行md5加密，然后再进行比对
        //对用户输入的文密加密
        password = DigestUtils.md5DigestAsHex(password.getBytes());

        if (!password.equals(employee.getPassword())) {
            //密码错误
            throw new PasswordErrorException(MessageConstant.PASSWORD_ERROR);
        }

        if (employee.getStatus() == StatusConstant.DISABLE) {
            //账号被锁定
            throw new AccountLockedException(MessageConstant.ACCOUNT_LOCKED);
        }

        //3、返回实体对象
        return employee;
    }


    /**
     * 新增员工
     * @param employeeDTO
     */
    @Override
    public void save(EmployeeDTO employeeDTO) {
        //1.将employeeDTO封装给employee对象
        //工具类: BeanUtils.copyProperties(A,B)
        //作用 : 将A对象中的属性值付给B对象相同的属性,进行属性拷贝
        Employee employee = new Employee();
        BeanUtils.copyProperties(employeeDTO,employee);

        //2.封装前端没有传递员工对象的数据密码
        //密码，默认设置为123456  记住密码要加密 md5
        employee.setPassword(DigestUtils.md5DigestAsHex(PasswordConstant.DEFAULT_PASSWORD.getBytes()));

        //状态，默认设置员工对象为启用
        employee.setStatus(StatusConstant.ENABLE);

//        //设置当前记录的创建时间和修改时间
//        employee.setCreateTime(LocalDateTime.now());
//        employee.setUpdateTime(LocalDateTime.now());
//        // TODO 设置当前记录创建人id和修改人id 写死 待完善
//        //employee.setCreateUser(1L);
//        //employee.setUpdateUser(1L);

        //利用ThreadLocal来改善
        employee.setCreateUser(BaseContext.getCurrentId());
        employee.setUpdateUser(BaseContext.getCurrentId());

        //3.调用mapper(数据访问层)插入数据库
        employeeMapper.save(employee);
    }

    /**
     * 员工分页查询
     * 分页介绍：
     *    分页原理sql语句
     *    第一条语句： 查询总条数 select count(*) from 表名
     *    第二条语句： 查询当前页数据列表 select * from 表名 where 条件 limit start(表示从第几页开始),length(长度)
     *    前端给的已知条件： 当前页码page,每页大小 pageSize
     *              得出 start = (page-1)*pageSize
     *                  length = pageSize
     *  PageHelper插件： 使用mybatis框架的插件，目的简化分页开发
     *                  实现的原理： 开发者只需要使用mybatis执行一条所有数据的sql语句 select * from 表名 where 条件
     *                              PageHelper自动通过动态代理获取上面的sql语句转换为2条原理sql语句查询总条数与每页数据列表执行
     *
     * @param employeePageQueryDTO
     * @return
     */
    @Override
    public PageResult page(EmployeePageQueryDTO employeePageQueryDTO) {
        //这里拓展新的分页查询工具 PageHelper
        //导入PageHelper的依赖(已经导入)
        //1.PagHelper设置当前页码和每页显示的数据
        PageHelper.startPage(employeePageQueryDTO.getPage(),employeePageQueryDTO.getPageSize());

        //2.调用mapper执行查询数据的sql语句,返回值必须为page对象(PageHelper提供的类)
        //page里面就有总条数和当前数据列表
        Page<Employee> page = employeeMapper.page(employeePageQueryDTO);

        //3.将page里面的数据封装给PageHelper
        //Page.getResult() 获取当前页码数据列表
        PageResult pageResult = new PageResult(page.getTotal(), page.getResult());
        //返回
        return pageResult;
    }


    /**
     * 设置员工状态
      * @param status
     * @param id
     */
    @Override
    public void startOrStop(Integer status,Long id) {
        //将上面的数据封装到Employee对象中
        Employee employee = Employee.builder()
                .id(id)
                .status(status)
                .updateTime(LocalDateTime.now())
                .updateUser(BaseContext.getCurrentId())
                .build();

        //调用mapper设置员工状态
        employeeMapper.update(employee);

    }

    @Override
    public Employee findById(Long id) {
        return employeeMapper.findById(id);
    }

    @Override
    public void update(EmployeeDTO employeeDTO) {
        Employee employee = new Employee();
        BeanUtils.copyProperties(employeeDTO,employee);

//        employee.setUpdateUser(BaseContext.getCurrentId());
//        employee.setUpdateTime(LocalDateTime.now());

        employeeMapper.update(employee);

    }
}
